#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
增强版中文可视化模块
专门解决matplotlib中文字体显示问题
"""

import matplotlib.pyplot as plt
import matplotlib.font_manager as fm
import matplotlib
import seaborn as sns
import numpy as np
import pandas as pd
from typing import Dict, List, Any, Optional, Tuple
import warnings
import os
import sys
from pathlib import Path

warnings.filterwarnings('ignore')

class ChineseFontManager:
    """
    中文字体管理器
    """
    
    def __init__(self):
        self.available_fonts = self._detect_chinese_fonts()
        self.current_font = self._select_best_font()
        self._configure_matplotlib()
    
    def _detect_chinese_fonts(self) -> List[str]:
        """
        检测系统可用的中文字体
        """
        print("🔍 正在检测系统中文字体...")
        
        # 常见中文字体列表
        target_fonts = [
            'Microsoft YaHei',
            'SimHei', 
            'SimSun',
            'KaiTi',
            'FangSong',
            'Microsoft JhengHei',
            'PingFang SC',
            'Hiragino Sans GB',
            'STHeiti',
            'WenQuanYi Micro Hei',
            'Noto Sans CJK SC',
            'Source Han Sans SC'
        ]
        
        available_fonts = []
        font_list = fm.findSystemFonts(fontpaths=None, fontext='ttf')
        
        for font_path in font_list:
            try:
                font_prop = fm.FontProperties(fname=font_path)
                font_name = font_prop.get_name()
                
                for target in target_fonts:
                    if target.lower() in font_name.lower():
                        if target not in available_fonts:
                            available_fonts.append(target)
                            print(f"   ✅ 找到字体: {target}")
                        break
            except Exception:
                continue
        
        if not available_fonts:
            print("   ⚠️ 未找到中文字体，将使用默认字体")
            available_fonts = ['DejaVu Sans', 'Arial']
        
        return available_fonts
    
    def _select_best_font(self) -> str:
        """
        选择最佳中文字体
        """
        # 字体优先级
        priority_order = [
            'Microsoft YaHei',
            'SimHei',
            'PingFang SC',
            'Hiragino Sans GB',
            'SimSun',
            'KaiTi'
        ]
        
        for font in priority_order:
            if font in self.available_fonts:
                print(f"🎯 选择字体: {font}")
                return font
        
        # 如果没有找到优先字体，使用第一个可用字体
        if self.available_fonts:
            font = self.available_fonts[0]
            print(f"🎯 使用字体: {font}")
            return font
        
        print("🎯 使用默认字体: DejaVu Sans")
        return 'DejaVu Sans'
    
    def _configure_matplotlib(self):
        """
        配置matplotlib中文字体
        """
        print("⚙️ 正在配置matplotlib中文字体...")
        
        # 清除matplotlib字体缓存
        try:
            cache_dir = matplotlib.get_cachedir()
            cache_files = Path(cache_dir).glob('*.cache')
            for cache_file in cache_files:
                cache_file.unlink(missing_ok=True)
            print("   清除字体缓存完成")
        except Exception as e:
            print(f"   清除字体缓存失败: {e}")
        
        # 重新构建字体缓存
        try:
            fm.fontManager.__init__()
            print("   重新构建字体缓存完成")
        except Exception as e:
            print(f"   重新构建字体缓存失败: {e}")
        
        # 设置字体配置
        font_list = [self.current_font] + self.available_fonts + ['DejaVu Sans', 'Arial']
        
        # 全局配置
        plt.rcParams['font.sans-serif'] = font_list
        plt.rcParams['font.family'] = 'sans-serif'
        plt.rcParams['axes.unicode_minus'] = False
        plt.rcParams['font.size'] = 12
        plt.rcParams['axes.titlesize'] = 14
        plt.rcParams['axes.labelsize'] = 12
        plt.rcParams['xtick.labelsize'] = 10
        plt.rcParams['ytick.labelsize'] = 10
        plt.rcParams['legend.fontsize'] = 10
        plt.rcParams['figure.titlesize'] = 16
        
        # matplotlib全局配置
        matplotlib.rcParams['font.sans-serif'] = font_list
        matplotlib.rcParams['font.family'] = 'sans-serif'
        matplotlib.rcParams['axes.unicode_minus'] = False
        matplotlib.rcParams['font.size'] = 12
        
        # 设置后端
        try:
            plt.switch_backend('Agg')
            print("   设置后端为Agg")
        except Exception as e:
            print(f"   设置后端失败: {e}")
        
        print("✅ 中文字体配置完成")
    
    def test_chinese_display(self, save_path: str = "chinese_font_test.png") -> str:
        """
        测试中文字体显示效果
        """
        print("🧪 正在测试中文字体显示...")
        
        fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2, figsize=(16, 12))
        fig.suptitle('中文字体显示测试报告', fontsize=18, fontweight='bold')
        
        # 测试1: 条形图
        categories = ['算法性能', '执行效率', '解质量', '稳定性', '收敛速度']
        values = [0.85, 0.92, 0.78, 0.88, 0.75]
        colors = ['#FF6B6B', '#4ECDC4', '#45B7D1', '#96CEB4', '#FFEAA7']
        
        bars = ax1.bar(categories, values, color=colors)
        ax1.set_title('算法性能评估', fontweight='bold', fontsize=14)
        ax1.set_ylabel('评分', fontsize=12)
        ax1.set_ylim(0, 1)
        
        # 添加数值标签
        for bar, value in zip(bars, values):
            height = bar.get_height()
            ax1.text(bar.get_x() + bar.get_width()/2., height + 0.02,
                    f'{value:.2f}', ha='center', va='bottom', fontweight='bold')
        
        # 测试2: 饼图
        suppliers = ['供应商A', '供应商B', '供应商C', '供应商D', '供应商E']
        quantities = [30, 25, 20, 15, 10]
        colors_pie = ['#FF9999', '#66B2FF', '#99FF99', '#FFCC99', '#FF99CC']
        
        wedges, texts, autotexts = ax2.pie(quantities, labels=suppliers, colors=colors_pie,
                                          autopct='%1.1f%%', startangle=90)
        ax2.set_title('供应商订购量分布', fontweight='bold', fontsize=14)
        
        # 美化饼图文字
        for autotext in autotexts:
            autotext.set_color('white')
            autotext.set_fontweight('bold')
            autotext.set_fontsize(10)
        
        # 测试3: 折线图
        iterations = list(range(1, 11))
        objective_values = [100, 85, 72, 65, 58, 52, 48, 45, 43, 42]
        
        ax3.plot(iterations, objective_values, 'o-', linewidth=3, markersize=8, 
                color='#E74C3C', markerfacecolor='white', markeredgewidth=2)
        ax3.set_title('目标函数收敛过程', fontweight='bold', fontsize=14)
        ax3.set_xlabel('迭代次数', fontsize=12)
        ax3.set_ylabel('目标函数值', fontsize=12)
        ax3.grid(True, alpha=0.3)
        
        # 测试4: 散点图
        np.random.seed(42)
        cost = np.random.normal(100, 20, 50)
        quality = np.random.normal(80, 15, 50)
        
        scatter = ax4.scatter(cost, quality, c=quality, cmap='viridis', 
                            s=100, alpha=0.7, edgecolors='black', linewidth=1)
        ax4.set_title('成本-质量关系分析', fontweight='bold', fontsize=14)
        ax4.set_xlabel('成本', fontsize=12)
        ax4.set_ylabel('质量评分', fontsize=12)
        ax4.grid(True, alpha=0.3)
        
        # 添加颜色条
        cbar = plt.colorbar(scatter, ax=ax4)
        cbar.set_label('质量评分', rotation=270, labelpad=15)
        
        plt.tight_layout()
        plt.savefig(save_path, dpi=300, bbox_inches='tight', facecolor='white')
        plt.close()
        
        print(f"✅ 中文字体测试完成，图片保存为: {save_path}")
        return save_path

class EnhancedChineseVisualizer:
    """
    增强版中文可视化器
    """
    
    def __init__(self):
        self.font_manager = ChineseFontManager()
        self.colors = ['#FF6B6B', '#4ECDC4', '#45B7D1', '#96CEB4', '#FFEAA7', 
                      '#DDA0DD', '#98D8C8', '#F7DC6F', '#BB8FCE', '#85C1E9']
    
    def create_supply_chain_dashboard(self, 
                                    optimization_result: Dict[str, Any],
                                    save_path: str = "supply_chain_dashboard.png") -> str:
        """
        创建供应链优化仪表板
        """
        print("📊 正在创建供应链优化仪表板...")
        
        fig = plt.figure(figsize=(20, 16))
        gs = fig.add_gridspec(4, 4, hspace=0.3, wspace=0.3)
        
        # 主标题
        fig.suptitle('供应链优化决策分析仪表板', fontsize=24, fontweight='bold', y=0.95)
        
        # 1. 供应商订购量分布 (左上)
        ax1 = fig.add_subplot(gs[0, :2])
        if 'best_solution' in optimization_result:
            solution = optimization_result['best_solution']
            suppliers = [f'供应商{i+1}' for i in range(len(solution))]
            quantities = list(solution.values())
            
            bars = ax1.bar(suppliers, quantities, color=self.colors[:len(suppliers)])
            ax1.set_title('各供应商最优订购量', fontweight='bold', fontsize=16)
            ax1.set_ylabel('订购量', fontsize=12)
            
            # 添加数值标签
            for bar, qty in zip(bars, quantities):
                height = bar.get_height()
                ax1.text(bar.get_x() + bar.get_width()/2., height + height*0.01,
                        f'{qty:.1f}', ha='center', va='bottom', fontweight='bold')
        
        # 2. 成本结构分析 (右上)
        ax2 = fig.add_subplot(gs[0, 2:])
        cost_categories = ['采购成本', '运输成本', '库存成本', '管理成本']
        cost_values = [150, 25, 10, 5]  # 示例数据
        colors_pie = self.colors[:len(cost_categories)]
        
        wedges, texts, autotexts = ax2.pie(cost_values, labels=cost_categories, 
                                          colors=colors_pie, autopct='%1.1f%%', 
                                          startangle=90)
        ax2.set_title('总成本结构分析', fontweight='bold', fontsize=16)
        
        for autotext in autotexts:
            autotext.set_color('white')
            autotext.set_fontweight('bold')
        
        # 3. 关键指标展示 (中左)
        ax3 = fig.add_subplot(gs[1, :2])
        ax3.axis('off')
        
        # 创建指标卡片
        metrics = [
            ('最优总成本', f"{optimization_result.get('best_objective_value', 0):.2f}", '成本单位'),
            ('执行时间', f"{optimization_result.get('execution_time', 0):.4f}", '秒'),
            ('算法类型', optimization_result.get('algorithm', '未知'), ''),
            ('收敛状态', '已收敛' if optimization_result.get('converged', False) else '未收敛', '')
        ]
        
        for i, (name, value, unit) in enumerate(metrics):
            x = 0.25 * (i % 2)
            y = 0.7 - 0.4 * (i // 2)
            
            # 绘制卡片背景
            rect = plt.Rectangle((x, y), 0.2, 0.25, facecolor=self.colors[i], alpha=0.3)
            ax3.add_patch(rect)
            
            # 添加文字
            ax3.text(x + 0.1, y + 0.18, name, ha='center', va='center', 
                    fontsize=12, fontweight='bold')
            ax3.text(x + 0.1, y + 0.1, value, ha='center', va='center', 
                    fontsize=14, fontweight='bold', color='red')
            ax3.text(x + 0.1, y + 0.05, unit, ha='center', va='center', 
                    fontsize=10, style='italic')
        
        ax3.set_xlim(0, 0.5)
        ax3.set_ylim(0, 1)
        ax3.set_title('关键性能指标', fontweight='bold', fontsize=16)
        
        # 4. 供应商产能利用率 (中右)
        ax4 = fig.add_subplot(gs[1, 2:])
        if 'best_solution' in optimization_result:
            # 假设的产能上限
            capacities = [50, 40, 35, 45, 30]
            utilization = [quantities[i]/capacities[i]*100 for i in range(len(quantities))]
            
            bars = ax4.barh(suppliers, utilization, color=self.colors[:len(suppliers)])
            ax4.set_title('供应商产能利用率', fontweight='bold', fontsize=16)
            ax4.set_xlabel('利用率 (%)', fontsize=12)
            ax4.set_xlim(0, 110)
            
            # 添加数值标签
            for bar, util in zip(bars, utilization):
                width = bar.get_width()
                ax4.text(width + 1, bar.get_y() + bar.get_height()/2.,
                        f'{util:.1f}%', ha='left', va='center', fontweight='bold')
        
        # 5. 风险评估雷达图 (下左)
        ax5 = fig.add_subplot(gs[2, :2], projection='polar')
        
        risk_categories = ['供应风险', '成本风险', '质量风险', '交期风险', '市场风险']
        risk_scores = [0.3, 0.2, 0.4, 0.25, 0.35]  # 风险评分 (0-1)
        
        angles = np.linspace(0, 2 * np.pi, len(risk_categories), endpoint=False).tolist()
        angles += angles[:1]
        risk_scores += risk_scores[:1]
        
        ax5.plot(angles, risk_scores, 'o-', linewidth=3, color='red', alpha=0.7)
        ax5.fill(angles, risk_scores, alpha=0.25, color='red')
        ax5.set_xticks(angles[:-1])
        ax5.set_xticklabels(risk_categories)
        ax5.set_ylim(0, 1)
        ax5.set_title('风险评估雷达图', fontweight='bold', fontsize=16, pad=20)
        
        # 6. 优化建议 (下右)
        ax6 = fig.add_subplot(gs[2, 2:])
        ax6.axis('off')
        
        recommendations = [
            "✅ 供应商1产能充分利用，建议保持",
            "⚠️ 供应商5成本较高，考虑价格谈判",
            "📈 总体方案成本控制良好",
            "🔄 建议定期重新评估供应商绩效",
            "📊 可考虑引入新供应商增加竞争"
        ]
        
        ax6.text(0.05, 0.9, '优化建议', fontsize=16, fontweight='bold')
        for i, rec in enumerate(recommendations):
            ax6.text(0.05, 0.75 - i*0.12, rec, fontsize=11, 
                    bbox=dict(boxstyle="round,pad=0.3", facecolor=self.colors[i], alpha=0.3))
        
        ax6.set_xlim(0, 1)
        ax6.set_ylim(0, 1)
        
        # 7. 算法性能对比 (底部)
        ax7 = fig.add_subplot(gs[3, :])
        
        algorithms = ['差分进化', '遗传算法', '粒子群优化', '模拟退火', '穷举搜索']
        performance_scores = [0.95, 0.88, 0.82, 0.79, 0.98]
        execution_times = [0.02, 0.15, 0.12, 0.18, 0.001]
        
        # 双轴图
        ax7_twin = ax7.twinx()
        
        bars1 = ax7.bar([x - 0.2 for x in range(len(algorithms))], performance_scores, 
                       width=0.4, color=self.colors[0], alpha=0.7, label='性能评分')
        bars2 = ax7_twin.bar([x + 0.2 for x in range(len(algorithms))], execution_times, 
                            width=0.4, color=self.colors[1], alpha=0.7, label='执行时间')
        
        ax7.set_title('算法性能对比分析', fontweight='bold', fontsize=16)
        ax7.set_xlabel('优化算法', fontsize=12)
        ax7.set_ylabel('性能评分', fontsize=12, color=self.colors[0])
        ax7_twin.set_ylabel('执行时间 (秒)', fontsize=12, color=self.colors[1])
        
        ax7.set_xticks(range(len(algorithms)))
        ax7.set_xticklabels(algorithms, rotation=45)
        ax7.set_ylim(0, 1.1)
        ax7_twin.set_ylim(0, max(execution_times) * 1.2)
        
        # 添加图例
        lines1, labels1 = ax7.get_legend_handles_labels()
        lines2, labels2 = ax7_twin.get_legend_handles_labels()
        ax7.legend(lines1 + lines2, labels1 + labels2, loc='upper right')
        
        plt.savefig(save_path, dpi=300, bbox_inches='tight', facecolor='white')
        plt.close()
        
        print(f"✅ 供应链优化仪表板创建完成: {save_path}")
        return save_path
    
    def create_algorithm_comparison_chart(self, 
                                        comparison_data: Dict[str, Any],
                                        save_path: str = "algorithm_comparison_enhanced.png") -> str:
        """
        创建增强版算法比较图表
        """
        print("📊 正在创建增强版算法比较图表...")
        
        fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2, figsize=(16, 12))
        fig.suptitle('算法性能深度对比分析', fontsize=18, fontweight='bold')
        
        # 示例数据
        algorithms = ['差分进化算法', '遗传算法', '粒子群优化', '模拟退火算法', '穷举搜索']
        objective_values = [190.0, 195.2, 198.5, 201.3, 190.0]
        execution_times = [0.0203, 0.156, 0.124, 0.189, 0.001]
        convergence_rates = [0.95, 0.88, 0.82, 0.75, 1.0]
        memory_usage = [12.5, 18.3, 15.7, 14.2, 8.1]
        
        # 1. 目标函数值对比
        bars1 = ax1.bar(algorithms, objective_values, color=self.colors[:len(algorithms)])
        ax1.set_title('目标函数值对比', fontweight='bold', fontsize=14)
        ax1.set_ylabel('目标函数值', fontsize=12)
        ax1.tick_params(axis='x', rotation=45)
        
        # 标注最优值
        min_idx = objective_values.index(min(objective_values))
        bars1[min_idx].set_color('gold')
        bars1[min_idx].set_edgecolor('red')
        bars1[min_idx].set_linewidth(3)
        
        for bar, value in zip(bars1, objective_values):
            height = bar.get_height()
            ax1.text(bar.get_x() + bar.get_width()/2., height + height*0.005,
                    f'{value:.1f}', ha='center', va='bottom', fontweight='bold')
        
        # 2. 执行时间对比 (对数尺度)
        bars2 = ax2.bar(algorithms, execution_times, color=self.colors[:len(algorithms)])
        ax2.set_title('执行时间对比 (对数尺度)', fontweight='bold', fontsize=14)
        ax2.set_ylabel('执行时间 (秒)', fontsize=12)
        ax2.set_yscale('log')
        ax2.tick_params(axis='x', rotation=45)
        
        for bar, time in zip(bars2, execution_times):
            height = bar.get_height()
            ax2.text(bar.get_x() + bar.get_width()/2., height * 1.1,
                    f'{time:.4f}s', ha='center', va='bottom', fontweight='bold')
        
        # 3. 综合性能雷达图
        categories = ['目标值优化', '执行效率', '收敛性', '内存效率', '稳定性']
        
        # 标准化数据 (越高越好)
        max_obj = max(objective_values)
        max_time = max(execution_times)
        max_memory = max(memory_usage)
        
        angles = np.linspace(0, 2 * np.pi, len(categories), endpoint=False).tolist()
        angles += angles[:1]
        
        ax3 = plt.subplot(2, 2, 3, projection='polar')
        ax3.set_title('综合性能雷达图', fontweight='bold', fontsize=14, pad=20)
        
        # 绘制前三个算法的雷达图
        for i in range(min(3, len(algorithms))):
            values = [
                1 - (objective_values[i] - min(objective_values)) / (max_obj - min(objective_values)) if max_obj != min(objective_values) else 1,
                1 - execution_times[i] / max_time,
                convergence_rates[i],
                1 - memory_usage[i] / max_memory,
                0.9 if i == 0 else 0.7  # 稳定性评分
            ]
            values += values[:1]
            
            ax3.plot(angles, values, 'o-', linewidth=2, 
                    label=algorithms[i], color=self.colors[i])
            ax3.fill(angles, values, alpha=0.25, color=self.colors[i])
        
        ax3.set_xticks(angles[:-1])
        ax3.set_xticklabels(categories)
        ax3.set_ylim(0, 1)
        ax3.legend(loc='upper right', bbox_to_anchor=(1.3, 1.0))
        
        # 4. 算法推荐矩阵
        ax4.axis('off')
        
        # 创建推荐表格
        scenarios = ['小规模问题', '中规模问题', '大规模问题', '实时优化', '高精度要求']
        recommendations = [
            ['穷举搜索', '差分进化', '遗传算法', '粒子群优化', '模拟退火'],
            ['差分进化', '遗传算法', '粒子群优化', '模拟退火', '穷举搜索'],
            ['遗传算法', '粒子群优化', '差分进化', '模拟退火', '穷举搜索'],
            ['差分进化', '粒子群优化', '遗传算法', '模拟退火', '穷举搜索'],
            ['穷举搜索', '差分进化', '遗传算法', '粒子群优化', '模拟退火']
        ]
        
        ax4.text(0.5, 0.95, '算法选择推荐矩阵', ha='center', va='top', 
                fontsize=14, fontweight='bold')
        
        for i, (scenario, rec_list) in enumerate(zip(scenarios, recommendations)):
            y_pos = 0.85 - i * 0.15
            ax4.text(0.05, y_pos, f'{scenario}:', fontweight='bold', fontsize=11)
            ax4.text(0.25, y_pos, f'推荐: {rec_list[0]}', fontsize=10, 
                    bbox=dict(boxstyle="round,pad=0.3", facecolor='lightgreen', alpha=0.7))
            ax4.text(0.25, y_pos - 0.05, f'备选: {rec_list[1]}, {rec_list[2]}', 
                    fontsize=9, style='italic')
        
        ax4.set_xlim(0, 1)
        ax4.set_ylim(0, 1)
        
        plt.tight_layout()
        plt.savefig(save_path, dpi=300, bbox_inches='tight', facecolor='white')
        plt.close()
        
        print(f"✅ 增强版算法比较图表创建完成: {save_path}")
        return save_path

# 全局实例
font_manager = ChineseFontManager()
enhanced_visualizer = EnhancedChineseVisualizer()

def test_enhanced_visualization():
    """
    测试增强版可视化功能
    """
    print("🚀 开始测试增强版中文可视化功能")
    print("=" * 50)
    
    # 测试字体显示
    font_manager.test_chinese_display("enhanced_chinese_test.png")
    
    # 测试供应链仪表板
    test_result = {
        'best_solution': {'x1': 50.0, 'x2': 40.0, 'x3': 35.0, 'x4': 45.0, 'x5': 30.0},
        'best_objective_value': 190.0,
        'execution_time': 0.0203,
        'algorithm': '差分进化算法',
        'converged': True
    }
    
    enhanced_visualizer.create_supply_chain_dashboard(test_result, "enhanced_supply_chain_dashboard.png")
    
    # 测试算法比较
    enhanced_visualizer.create_algorithm_comparison_chart({}, "enhanced_algorithm_comparison.png")
    
    print("✅ 增强版中文可视化功能测试完成")

if __name__ == "__main__":
    test_enhanced_visualization()